package com.premize.grco.movil.control;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.premize.grco.dataaccess.daoFactory.XMLHibernateDaoFactory;
import com.premize.grco.dataaccess.sessionFactory.HibernateSessionFactory;
import com.premize.grco.exceptions.ExceptionManager;
import com.premize.grco.exceptions.ExceptionMessages;
import com.premize.grco.movil.GrcoPDescuento;
import com.premize.grco.movil.GrcoProducto;
import com.premize.grco.utilities.Utilities;


/**
 * interface GrcoPDescuentoLogic
 * @author Zathura Code Generator http://code.google.com/p/zathura
 *
 */
public class GrcoPDescuentoLogic implements IGrcoPDescuentoLogic {
	public List<GrcoPDescuento> getGrcoPDescuento() throws Exception {
		List<GrcoPDescuento> list = new ArrayList<GrcoPDescuento>();

		try {
			list = XMLHibernateDaoFactory.getInstance().getGrcoPDescuentoDAO()
			.findAll();
		} catch (Exception e) {
			throw new Exception(ExceptionManager.getInstance()
					.exceptionInGetAll());
		} finally {
			HibernateSessionFactory.closeSession();
		}

		return list;
	}

	public void saveGrcoPDescuento(Long tipoDescuento,
			Double valor) throws Exception {
		GrcoPDescuento entity = null;

		try {
//			if (consDescuento == null) {
//				throw new Exception(ExceptionMessages.VARIABLE_NULL +
//						"consDescuento");
//			}

//			if ((consDescuento != null) &&
//					(Utilities.checkNumberAndCheckWithPrecisionAndScale("" +
//							consDescuento, 10, 0) == false)) {
//				throw new Exception(ExceptionMessages.VARIABLE_LENGTH +
//				"consDescuento");
//			}

			if (tipoDescuento == null) {
				throw new Exception(ExceptionMessages.VARIABLE_NULL +
						"tipoDescuento");
			}

			if ((tipoDescuento != null) &&
					(Utilities.checkNumberAndCheckWithPrecisionAndScale("" +
							tipoDescuento, 10, 0) == false)) {
				throw new Exception(ExceptionMessages.VARIABLE_LENGTH +
				"tipoDescuento");
			}

			if (valor == null) {
				throw new Exception(ExceptionMessages.VARIABLE_NULL + "valor");
			}

			if ((valor != null) &&
					(Utilities.checkNumberAndCheckWithPrecisionAndScale("" +
							valor, 15, 2) == false)) {
				throw new Exception(ExceptionMessages.VARIABLE_LENGTH +
				"valor");
			}

			List<GrcoPDescuento> list = findByCriteria(new Object[]{"valor", false, valor, "="}, null, null);

			if (list != null && !list.isEmpty()) {
				entity = list.get(0);
			}
			
			if (entity != null) {
				throw new Exception(ExceptionMessages.ENTITY_WITHSAMEKEY);
			}

			entity = new GrcoPDescuento();
//			entity.setConsDescuento(consDescuento);
			entity.setTipoDescuento(tipoDescuento);
			entity.setValor(valor);
			HibernateSessionFactory.beginTransaction();
			XMLHibernateDaoFactory.getInstance().getGrcoPDescuentoDAO()
			.save(entity);
			HibernateSessionFactory.commit();
		} catch (Exception e) {
			HibernateSessionFactory.rollback();
			throw e;
		} finally {
			HibernateSessionFactory.closeSession();
		}
	}

	public void deleteGrcoPDescuento(Long consDescuento)
	throws Exception {
		GrcoPDescuento entity = null;

		if (consDescuento == null) {
			throw new Exception(ExceptionMessages.VARIABLE_NULL);
		}

		List<GrcoProducto> grcoProductos = null;
		entity = getGrcoPDescuento(consDescuento);

		if (entity == null) {
			throw new Exception(ExceptionMessages.ENTITY_NULL);
		}

		try {
			grcoProductos = XMLHibernateDaoFactory.getInstance()
			.getGrcoProductoDAO()
			.findByProperty("grcoPDescuento.consDescuento",
					consDescuento);

			if (Utilities.validationsList(grcoProductos) == false) {
				throw new Exception(ExceptionManager.getInstance()
						.exceptionDeletingEntityWithChild());
			}

			HibernateSessionFactory.beginTransaction();
			XMLHibernateDaoFactory.getInstance().getGrcoPDescuentoDAO()
			.delete(entity);
			HibernateSessionFactory.commit();
		} catch (Exception e) {
			HibernateSessionFactory.rollback();
			throw e;
		} finally {
			HibernateSessionFactory.closeSession();
		}
	}

	public void updateGrcoPDescuento(Long consDescuento, Long tipoDescuento,
			Double valor) throws Exception {
		GrcoPDescuento entity = null;

		try {
			if (consDescuento == null) {
				throw new Exception(ExceptionMessages.VARIABLE_NULL +
						"consDescuento");
			}

			if ((consDescuento != null) &&
					(Utilities.checkNumberAndCheckWithPrecisionAndScale("" +
							consDescuento, 10, 0) == false)) {
				throw new Exception(ExceptionMessages.VARIABLE_LENGTH +
				"consDescuento");
			}

			if (tipoDescuento == null) {
				throw new Exception(ExceptionMessages.VARIABLE_NULL +
						"tipoDescuento");
			}

			if ((tipoDescuento != null) &&
					(Utilities.checkNumberAndCheckWithPrecisionAndScale("" +
							tipoDescuento, 10, 0) == false)) {
				throw new Exception(ExceptionMessages.VARIABLE_LENGTH +
				"tipoDescuento");
			}

			if (valor == null) {
				throw new Exception(ExceptionMessages.VARIABLE_NULL + "valor");
			}

			if ((valor != null) &&
					(Utilities.checkNumberAndCheckWithPrecisionAndScale("" +
							valor, 15, 0) == false)) {
				throw new Exception(ExceptionMessages.VARIABLE_LENGTH +
				"valor");
			}

			entity = getGrcoPDescuento(consDescuento);

			if (entity == null) {
				throw new Exception(ExceptionMessages.ENTITY_NOENTITYTOUPDATE);
			}

			entity.setConsDescuento(consDescuento);
			entity.setTipoDescuento(tipoDescuento);
			entity.setValor(valor);
			HibernateSessionFactory.beginTransaction();
			XMLHibernateDaoFactory.getInstance().getGrcoPDescuentoDAO()
			.update(entity);
			HibernateSessionFactory.commit();
		} catch (Exception e) {
			HibernateSessionFactory.rollback();
			throw e;
		} finally {
			HibernateSessionFactory.closeSession();
		}
	}

	public GrcoPDescuento getGrcoPDescuento(Long consDescuento)
	throws Exception {
		GrcoPDescuento entity = null;

		try {
			entity = XMLHibernateDaoFactory.getInstance().getGrcoPDescuentoDAO()
			.findById(consDescuento);
		} catch (Exception e) {
			throw new Exception(ExceptionManager.getInstance()
					.exceptionFindingEntity("GrcoPDescuento"));
		} finally {
			HibernateSessionFactory.closeSession();
		}

		return entity;
	}

	public List<GrcoPDescuento> findPageGrcoPDescuento(String sortColumnName,
			boolean sortAscending, int startRow, int maxResults)
			throws Exception {
		List<GrcoPDescuento> entity = null;

		try {
			entity = XMLHibernateDaoFactory.getInstance().getGrcoPDescuentoDAO()
			.findPageGrcoPDescuento(sortColumnName,
					sortAscending, startRow, maxResults);
		} catch (Exception e) {
			throw new Exception(ExceptionManager.getInstance()
					.exceptionFindingEntity("GrcoPDescuento"));
		} finally {
			HibernateSessionFactory.closeSession();
		}

		return entity;
	}

	public Long findTotalNumberGrcoPDescuento() throws Exception {
		Long entity = null;

		try {
			entity = XMLHibernateDaoFactory.getInstance().getGrcoPDescuentoDAO()
			.findTotalNumberGrcoPDescuento();
		} catch (Exception e) {
			throw new Exception(ExceptionManager.getInstance()
					.exceptionFindingEntity("GrcoPDescuento Count"));
		} finally {
			HibernateSessionFactory.closeSession();
		}

		return entity;
	}

	/**
	 *
	 * @param varibles
	 *            este arreglo debera tener:
	 *
	 * [0] = String variable = (String) varibles[i]; representa como se llama la
	 * variable en el pojo
	 *
	 * [1] = Boolean booVariable = (Boolean) varibles[i + 1]; representa si el
	 * valor necesita o no ''(comillas simples)usado para campos de tipo string
	 *
	 * [2] = Object value = varibles[i + 2]; representa el valor que se va a
	 * buscar en la BD
	 *
	 * [3] = String comparator = (String) varibles[i + 3]; representa que tipo
	 * de busqueda voy a hacer.., ejemplo: where nombre=william o where nombre<>william,
	 * en este campo iria el tipo de comparador que quiero si es = o <>
	 *
	 * Se itera de 4 en 4..., entonces 4 registros del arreglo representan 1
	 * busqueda en un campo, si se ponen mas pues el continuara buscando en lo
	 * que se le ingresen en los otros 4
	 *
	 *
	 * @param variablesBetween
	 *
	 * la diferencia son estas dos posiciones
	 *
	 * [0] = String variable = (String) varibles[j]; la variable ne la BD que va
	 * a ser buscada en un rango
	 *
	 * [1] = Object value = varibles[j + 1]; valor 1 para buscar en un rango
	 *
	 * [2] = Object value2 = varibles[j + 2]; valor 2 para buscar en un rango
	 * ejempolo: a > 1 and a < 5 --> 1 seria value y 5 seria value2
	 *
	 * [3] = String comparator1 = (String) varibles[j + 3]; comparador 1
	 * ejemplo: a comparator1 1 and a < 5
	 *
	 * [4] = String comparator2 = (String) varibles[j + 4]; comparador 2
	 * ejemplo: a comparador1>1  and a comparador2<5  (el original: a > 1 and a <
	 * 5) *
	 * @param variablesBetweenDates(en
	 *            este caso solo para mysql)
	 *  [0] = String variable = (String) varibles[k]; el nombre de la variable que hace referencia a
	 *            una fecha
	 *
	 * [1] = Object object1 = varibles[k + 2]; fecha 1 a comparar(deben ser
	 * dates)
	 *
	 * [2] = Object object2 = varibles[k + 3]; fecha 2 a comparar(deben ser
	 * dates)
	 *
	 * esto hace un between entre las dos fechas.
	 *
	 * @return lista con los objetos que se necesiten
	 * @throws Exception
	 */
	public List<GrcoPDescuento> findByCriteria(Object[] variables,
			Object[] variablesBetween, Object[] variablesBetweenDates)
			throws Exception {
		List<GrcoPDescuento> list = new ArrayList<GrcoPDescuento>();
		String where = new String();
		String tempWhere = new String();

		if (variables != null) {
			for (int i = 0; i < variables.length; i++) {
				if ((variables[i] != null) && (variables[i + 1] != null) &&
						(variables[i + 2] != null) &&
						(variables[i + 3] != null)) {
					String variable = (String) variables[i];
					Boolean booVariable = (Boolean) variables[i + 1];
					Object value = variables[i + 2];
					String comparator = (String) variables[i + 3];

					if (booVariable.booleanValue()) {
						tempWhere = (tempWhere.length() == 0)
						? ("(model." + variable + " " + comparator + " \'" +
								value + "\' )")
								: (tempWhere + " AND (model." + variable + " " +
										comparator + " \'" + value + "\' )");
					} else {
						tempWhere = (tempWhere.length() == 0)
						? ("(model." + variable + " " + comparator + " " +
								value + " )")
								: (tempWhere + " AND (model." + variable + " " +
										comparator + " " + value + " )");
					}
				}

				i = i + 3;
			}
		}

		if (variablesBetween != null) {
			for (int j = 0; j < variablesBetween.length; j++) {
				if ((variablesBetween[j] != null) &&
						(variablesBetween[j + 1] != null) &&
						(variablesBetween[j + 2] != null) &&
						(variablesBetween[j + 3] != null) &&
						(variablesBetween[j + 4] != null)) {
					String variable = (String) variablesBetween[j];
					Object value = variablesBetween[j + 1];
					Object value2 = variablesBetween[j + 2];
					String comparator1 = (String) variablesBetween[j + 3];
					String comparator2 = (String) variablesBetween[j + 4];
					tempWhere = (tempWhere.length() == 0)
					? ("(" + value + " " + comparator1 + " " + variable +
							" and " + variable + " " + comparator2 + " " + value2 +
							" )")
							: (tempWhere + " AND (" + value + " " + comparator1 +
									" " + variable + " and " + variable + " " +
									comparator2 + " " + value2 + " )");
				}

				j = j + 4;
			}
		}

		if (variablesBetweenDates != null) {
			for (int k = 0; k < variablesBetweenDates.length; k++) {
				if ((variablesBetweenDates[k] != null) &&
						(variablesBetweenDates[k + 1] != null) &&
						(variablesBetweenDates[k + 2] != null)) {
					String variable = (String) variablesBetweenDates[k];
					Object object1 = variablesBetweenDates[k + 1];
					Object object2 = variablesBetweenDates[k + 2];
					String value = null;
					String value2 = null;

					try {
						Date date1 = (Date) object1;
						Date date2 = (Date) object2;
						value = Utilities.formatDateWithoutTimeInAStringForBetweenWhere(date1);
						value2 = Utilities.formatDateWithoutTimeInAStringForBetweenWhere(date2);
					} catch (Exception e) {
						list = null;
						throw e;
					}

					tempWhere = (tempWhere.length() == 0)
					? ("(model." + variable + " between \'" + value +
							"\' and \'" + value2 + "\')")
							: (tempWhere + " AND (model." + variable +
									" between \'" + value + "\' and \'" + value2 + "\')");
				}

				k = k + 2;
			}
		}

		if (tempWhere.length() == 0) {
			where = null;
		} else {
			where = "(" + tempWhere + ")";
		}

		try {
			list = XMLHibernateDaoFactory.getInstance().getGrcoPDescuentoDAO()
			.findByCriteria(where);
		} catch (Exception e) {
			throw new Exception(e.getMessage());
		} finally {
			HibernateSessionFactory.closeSession();
		}

		return list;
	}
}
